
'''
    基金数据统计.py 中无用的一个函数，功能有相同的函数，这个算法有待商榷
'''
def sort_by_r2_(col_num:int=5,max_rates:int=20):
    '''
        分析各基金的增长率线性度，通过线性回归计算 R² 和 MSE 值来评估哪只基金的增长率更接近直线
    '''
    print('分析各基金的增长率线性度2 ')
    if os.path.exists(fund_data_file):
                df = pd.read_csv(fund_data_file,dtype={'基金代码':str})
    else:
        print('文件不存在，请先用-g参数获取数据')
        return

    # 时间周期（以天为单位）
    periods = np.array(COLUMNS_TO_ANALYZE_DAYS)
    period_names = COLUMNS_TO_ANALYZE

    # 评估每只基金增长率的线性度
    results = []
    for _, row in df.iterrows():

        # 获取基金名称
        fund_name = row['基金名称']
        fund_code = row['基金代码']
        
        # 获取增长率数据，跳过缺失值和NaN
        growth_rates = []
        valid_period_indices = []
        for i, name in enumerate(period_names):
            # 跳过多余数据
            if i == col_num:
                break
            value = row[name]
            if value is not None and not np.isnan(value):
                growth_rates.append(value)
                valid_period_indices.append(i)
        
        valid_periods = periods[valid_period_indices]
        
        # print(growth_rates)
        # 确保有足够的数据点进行线性回归
        # 去掉 增长率太小的数据
        if len(growth_rates) < col_num or growth_rates[col_num-2] <= max_rates:
            # print(f"跳过 {fund_name}：有效数据点不足")
            continue
        
        # 准备数据
        x = valid_periods.reshape(-1, 1)
        y = np.array(growth_rates)
        
        # 验证数据中不包含NaN
        if np.isnan(y).any():
            print(f"警告：{fund_name} 的增长率数据包含NaN，已跳过")
            continue
        
        # 线性回归
        model = LinearRegression()
        model.fit(x, y)
        y_pred = model.predict(x)
        
        # 计算评估指标
        r2 = model.score(x, y)
        mse = mean_squared_error(y, y_pred)
        
        # 去掉水平直线
        if r2 == 1 and mse == 0:
            continue

        results.append({
            '基金名称': fund_name,
            '代码': fund_code,
            'R²': r2,
            'MSE': mse,
            '斜率': model.coef_[0],
            '截距': model.intercept_,
            '增长率': growth_rates,
            '使用的周期': [period_names[i] for i in valid_period_indices]
        })
        
    print(f"筛选出{len(results)}条数据")
    if len(results) == 0:
        return

    # 转换为DataFrame方便分析
    results_df = pd.DataFrame(results)

    # 按R²降序排序（R²越接近1越好）
    results_df_sorted_by_r2 = results_df.sort_values('R²', ascending=False)

    # 按MSE升序排序（MSE越小越好）
    results_df_sorted_by_mse = results_df.sort_values('MSE', ascending=True)

    # 打印线性度最好的前5只基金
    print("按R²排序的前5只基金（增长率最接近直线）：")
    for _, row in results_df_sorted_by_r2.head(5).iterrows():
        print(f"基金名称: {row['基金名称']}, 代码: {row['代码']}")
        print(f"R²: {row['R²']:.4f}, MSE: {row['MSE']:.4f}")
        print(f"增长率: {np.round(row['增长率'], 2)}")
        print(f"使用的周期: {row['使用的周期']}")
        print(f"拟合直线: y = {row['斜率']:.6f}x + {row['截距']:.6f}")
        print("-" * 50)
        

# 3. 定义函数：计算每条曲线的拟合优度（R²和残差平方和）
def evaluate_linearity(x, y):
    """
    评估y随x变化的曲线与直线的接近程度
    返回：R²（越接近1越好）、残差平方和（SSE，越小越好）
    """
    # 过滤缺失值（若有）
    mask = ~np.isnan(x) & ~np.isnan(y)
    x_clean = x[mask].reshape(-1, 1)  # 线性回归要求x是二维数组
    y_clean = y[mask]
    
    # 数据点太少（<2个）无法拟合
    if len(x_clean) < 2:
        return -np.inf, np.inf  # R²最小，SSE最大
    
    # 线性拟合
    model = LinearRegression()
    model.fit(x_clean, y_clean)
    y_pred = model.predict(x_clean)  # 预测值（拟合直线上的点）
    
    # 计算评估指标
    r2 = r2_score(y_clean, y_pred)  # 决定系数
    sse = np.sum((y_clean - y_pred) **2)  # 残差平方和
    return r2, sse